package maxinshiSomeipTool20.common.itfSafeSWT;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.DateTime;

import java.util.Date;
import java.text.SimpleDateFormat;

/**
 * SWT 人机交互安全工具类
 * 封装控件数据读写的安全操作，防止null赋值、控件已释放导致的崩溃，附带日志记录
 */
public class SwtSafeDataUtil {

    // ====================== 1. 文本类控件安全赋值 ======================
    /**
     * 安全设置Text控件文本（防null、防控件已释放）
     */
    public static void setSafeText(Text text, String value) {
        if (!isControlValid(text)) {
            logEx("Text控件无效（null或已释放），无法设置文本");
            return;
        }
        String safeValue = (value == null) ? "" : value;
        text.setText(safeValue);
        logInfo("Text控件赋值成功，内容：" + safeValue);
    }

    /**
     * 安全设置Combo控件文本
     */
    public static void setSafeCombo(Combo combo, String value) {
        if (!isControlValid(combo)) {
            logEx("Combo控件无效（null或已释放），无法设置文本");
            return;
        }
        String safeValue = (value == null) ? "" : value;
        combo.setText(safeValue);
        logInfo("Combo控件赋值成功，内容：" + safeValue);
    }

    /**
     * 安全设置Label控件文本
     */
    public static void setSafeLabel(Label label, String value) {
        if (!isControlValid(label)) {
            logEx("Label控件无效（null或已释放），无法设置文本");
            return;
        }
        String safeValue = (value == null) ? "" : value;
        label.setText(safeValue);
        logInfo("Label控件赋值成功，内容：" + safeValue);
    }

    /**
     * 安全设置TreeItem节点文本
     */
    public static void setSafeTreeItemText(TreeItem treeItem, String value) {
        if (treeItem == null || treeItem.isDisposed()) {
            logEx("TreeItem节点无效（null或已释放），无法设置文本");
            return;
        }
        String safeValue = (value == null) ? "" : value;
        treeItem.setText(safeValue);
        logInfo("TreeItem节点赋值成功，内容：" + safeValue);
    }


    // ====================== 2. 表格控件安全操作 ======================
    /**
     * 安全设置表格单元格文本（防null、防控件已释放、防列索引越界）
     * @param item 表格行项
     * @param column 列索引（从0开始）
     * @param value 要设置的文本
     */
    public static void setSafeTableItemText(TableItem item, int column, String value) {
        // 1. 校验表格项有效性
        if (item == null || item.isDisposed()) {
            logEx("TableItem无效（null或已释放），无法设置单元格文本");
            return;
        }
        // 2. 校验列索引有效性
        if (column < 0 || column >= item.getParent().getColumnCount()) {
            logEx("表格列索引无效（column=" + column + "），表格实际列数：" + item.getParent().getColumnCount());
            return;
        }
        // 3. 处理null值
        String safeValue = (value == null) ? "" : value;
        item.setText(column, safeValue);
        logInfo("表格单元格（列" + column + "）赋值成功，内容：" + safeValue);
    }


    // ====================== 3. 复选框控件安全操作 ======================
    /**
     * 安全设置复选框选中状态（防控件已释放、防非复选框类型）
     * @param checkbox 复选框控件（必须是SWT.CHECK类型）
     * @param selected 是否选中
     */
    public static void setSafeCheckboxSelection(Button checkbox, boolean selected) {
        // 1. 校验控件有效性
        if (!isControlValid(checkbox)) {
            logEx("复选框控件无效（null或已释放），无法设置选中状态");
            return;
        }
        // 2. 校验控件类型（确保是复选框）
        if ((checkbox.getStyle() & SWT.CHECK) == 0) {
            logEx("控件不是复选框类型，无法设置选中状态");
            return;
        }
        // 3. 设置选中状态
        checkbox.setSelection(selected);
        logInfo("复选框选中状态设置为：" + selected);
    }

    /**
     * 安全获取复选框选中状态（防控件已释放）
     * @param checkbox 复选框控件
     * @return 选中状态（控件无效时返回false）
     */
    public static boolean getSafeCheckboxSelection(Button checkbox) {
        if (!isControlValid(checkbox) || (checkbox.getStyle() & SWT.CHECK) == 0) {
            logEx("复选框控件无效，无法获取选中状态");
            return false;
        }
        return checkbox.getSelection();
    }


    // ====================== 4. 日期控件安全操作 ======================
    /**
     * 安全设置日期控件值（处理null日期、防控件已释放）
     * @param dateTime 日期控件（SWT.DATE类型）
     * @param date 日期对象（可为null，null时不设置）
     */
    public static void setSafeDate(DateTime dateTime, Date date) {
        // 1. 校验控件有效性
        if (!isControlValid(dateTime)) {
            logEx("日期控件无效（null或已释放），无法设置日期");
            return;
        }
        // 2. 校验控件类型（确保是日期控件）
        if ((dateTime.getStyle() & SWT.DATE) == 0) {
            logEx("控件不是日期类型，无法设置日期");
            return;
        }
        // 3. 处理null日期（不操作，保留当前值）
        if (date == null) {
            logInfo("日期为null，不设置日期控件值");
            return;
        }
        // 4. 解析日期并设置（年、月、日）
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String[] dateParts = sdf.format(date).split("-");
        try {
            int year = Integer.parseInt(dateParts[0]);
            int month = Integer.parseInt(dateParts[1]) - 1; // SWT月份从0开始（0=1月）
            int day = Integer.parseInt(dateParts[2]);
            
            dateTime.setYear(year);
            dateTime.setMonth(month);
            dateTime.setDay(day);
            logInfo("日期控件设置成功：" + sdf.format(date));
        } catch (Exception e) {
            logEx("日期格式解析错误，无法设置日期：" + e.getMessage());
        }
    }

    /**
     * 安全获取日期控件的日期（防控件已释放）
     * @param dateTime 日期控件
     * @return 日期对象（控件无效时返回null）
     */
    public static Date getSafeDate(DateTime dateTime) {
        if (!isControlValid(dateTime) || (dateTime.getStyle() & SWT.DATE) == 0) {
            logEx("日期控件无效，无法获取日期");
            return null;
        }
        try {
            // SWT月份是0-based（0=1月），转换为实际月份需+1
            String dateStr = String.format("%d-%02d-%02d", 
                    dateTime.getYear(), 
                    dateTime.getMonth() + 1, 
                    dateTime.getDay());
            return new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
        } catch (Exception e) {
            logEx("获取日期失败：" + e.getMessage());
            return null;
        }
    }


    // ====================== 5. 控件数据安全读取 ======================
    /**
     * 安全读取Text控件文本
     */
    public static String getSafeText(Text text) {
        if (!isControlValid(text)) {
            logEx("Text控件无效（null或已释放），无法读取文本");
            return "";
        }
        String result = text.getText();
        return result == null ? "" : result;
    }

    /**
     * 安全读取Combo控件选中文本
     */
    public static String getSafeComboText(Combo combo) {
        if (!isControlValid(combo)) {
            logEx("Combo控件无效（null或已释放），无法读取文本");
            return "";
        }
        String result = combo.getText();
        return result == null ? "" : result;
    }

    /**
     * 安全读取List控件选中项
     */
    public static String[] getSafeListSelection(List list) {
        if (!isControlValid(list)) {
            logEx("List控件无效（null或已释放），无法读取选中项");
            return new String[0];
        }
        String[] selections = list.getSelection();
        return selections == null ? new String[0] : selections;
    }


    // ====================== 6. 控件状态安全操作 ======================
    /**
     * 安全设置控件启用/禁用状态
     */
    public static void setSafeEnabled(Control control, boolean enabled) {
        if (!isControlValid(control)) {
            logEx("控件无效（null或已释放），无法设置启用状态");
            return;
        }
        control.setEnabled(enabled);
        logInfo("控件[" + control.getClass().getSimpleName() + "]启用状态设置为：" + enabled);
    }

    /**
     * 安全设置控件可见性
     */
    public static void setSafeVisible(Control control, boolean visible) {
        if (!isControlValid(control)) {
            logEx("控件无效（null或已释放），无法设置可见性");
            return;
        }
        control.setVisible(visible);
        logInfo("控件[" + control.getClass().getSimpleName() + "]可见性设置为：" + visible);
    }


    // ====================== 7. 基础工具方法 ======================
    /**
     * 判断控件是否有效（非null + 未释放）
     */
    private static boolean isControlValid(Control control) {
        return control != null && !control.isDisposed();
    }

    /**
     * 错误日志记录（带时间戳）
     */
    private static void logEx(String message) {
        System.err.println("[" + new Date() + "] [SWT安全操作错误]：" + message);
    }

    /**
     * 普通信息日志记录
     */
    private static void logInfo(String message) {
        // 生产环境可注释
        // System.out.println("[" + new Date() + "] [SWT安全操作信息]：" + message);
    }
}
